<?php
class Exif {
	private $make;
	private $model;
	private $exposureTime;
	private $fNumber;
	private $focalLength;
	private $iso;
	private $flash;
	private $dateTime;
	private $jpegComment;
	private $userComment;
	private $imageDescription;

	function __construct($file) {
		// get all exif data from image
		$data = exif_read_data($file);
		// and then some of them extract and process. Make and model are
		// quite ok, but rest of it can be just mess.
		$this->make = $this->extractMake($data);
		$this->model = $this->extractModel($data, $this->make);
		$this->exposureTime = $this->extractExposureTime($data);
		$this->fNumber = $this->extractFNumber($data);
		$this->focalLength = $this->extractFocalLength($data);
		$this->iso = $this->extractIso($data, $this->make);
		$this->flash = $this->extractFlash($data);
		$this->dateTime = $this->extractDateTime($data);
		$this->jpegComment = $this->extractJpegComment($data);
		$this->userComment = $this->extractUserComment($data);
		$this->imageDescription = $this->extractImageDescription($data);
	}

	private function extractMake($exif_header) {
		if (isset($exif_header["Model"])) {
			$make=ucfirst(strtolower($exif_header["Make"]));
			if (stristr($make,"Nikon")) $make="Nikon";
			else if (stristr($make,"Olympus")) $make="Olympus";
			else if (stristr($make,"Minolta") && !stristr($make,"Konica")) $make="Minolta";
			else if (stristr($make,"Minolta")) $make="Konica Minolta";
			else if (stristr($make,"Kodak")) $make="Kodak";
			else if (stristr($make,"Asahi") || stristr($make,"Pentax")) $make="Pentax";
			else if (stristr($make,"Casio")) $make="Casio";
			else if (stristr($make,"Hewlett-packard")) $make="HP";
			if($make) {
				return trim($make);
			}
		}
		return NULL;
	}

	private function extractModel($exif_header, $make) {
		if (isset($exif_header["Model"])) {
			$model=$exif_header["Model"];
			if (stristr(strtolower($model),strtolower($make))) $model=eregi_replace($make,'',$model);
			// Special for Nikon Coolpix
			if ($make=="Nikon" && ereg("E([0-9])",$model)) $model=eregi_replace('E','CoolPix ',$model);
			// Special for HP cameras
			if ($make=="HP") {
				// Remove double brand
				$model = str_replace('HP ','', $model);
				// Remove firmware version from the model
				$model = preg_replace('/\(V[0-9]{2}\.[0-9]{2}\)$/', '', $model);
			}
			if ($model) {
				return trim($model);
			}
		}
		return NULL;
	}

	private function extractExposureTime($exif_header) {
		if (isset($exif_header['ExposureTime'])) {
			list($div,$exposureTime)=split("/", $exif_header['ExposureTime']);
			$exposureTime=$div/$exposureTime;
			if ($exposureTime < 1) $exposureTime="1/".round(1/$exposureTime,2);
		}
		elseif (isset($exif_header['ShutterSpeedValue'])) {
			list($exposureTime,$div)=split("/", $exif_header['ShutterSpeedValue']);
			$exposureTime=($div/10)/$exposureTime;
			if ($exposureTime < 1) $exposureTime="1/".round(1/$exposureTime,2);
		}
		elseif (isset($exif_header["COMPUTED"]["ExposureTime"])) {
			ereg(".*\((.*)\)",$exif_header["COMPUTED"]["ExposureTime"], $res);
			$exposureTime=$res[1];
		}
		if (isset($exposureTime)) {
			return $exposureTime;
		}
		return NULL;
	}

	private function extractFNumber($exif_header) {
		if (isset($exif_header["FNumber"])) {
			list($fNumber,$div)=split("/", $exif_header["FNumber"]);
			$fNumber=round($fNumber/$div,1);
		}
		else if (isset($exif_header["COMPUTED"]["ApertureFNumber"])) $fNumber=$exif_header["COMPUTED"]["ApertureFNumber"];
		if (isset($fNumber)) {
			return $fNumber;
		}
		return NULL;
	}

	private function extractFocalLength($exif_header) {
		if (isset($exif_header["FocalLength"])) {
			list($focalLength,$div)=split("/", $exif_header["FocalLength"]);
			$focalLength=round($focalLength/$div,2);
			if ($focalLength) {
				return $focalLength;
			}
		}
		return NULL;
	}

	private function extractIso($exif_header, $make) {
		$result = NULL;
		if (isset($exif_header["ISOSpeedRatings"])) {
			$result = $exif_header["ISOSpeedRatings"];
		} else {
			// Not standard exif... trying to get Make's specific data
			// Canon Stuff
			if ($make == "Canon") {
				if (isset($exif_header["ModeArray"][16])) {
					switch ($exif_header["ModeArray"][16]) {
						case 15:
							$result="Auto";
							break;
						case 16:
							$result=50;
							break;
						case 17:
							$result=100;
							break;
						case 18:
							$result=200;
							break;
						case 19:
							$result=400;
							break;
					}
				}
			}
		}
		return $result;
	}

	private function extractFlash($exif_header) {
		if(isset($exif_header['Flash'])) {
			return $exif_header['Flash'];
		}
		return NULL;
	}

	private function extractDateTime($exif_header) {
		if (isset($exif_header['DateTimeOriginal'])) {
			return ereg_replace("([0-9]{4}):([0-9]{2}):([0-9]{2})()","\\1-\\2-\\3\\4",$exif_header['DateTimeOriginal']);
		}
		return NULL;
	}

	private function extractJpegComment($exif_header) {
		if (isset($exif_header['COMMENT'])) {
			// So far, I've only seen row in the COMMENT array such, no loop has been implemented
			return $exif_header['COMMENT'][0];
		}
		return NULL;
	}

	private function extractUserComment($exif_header) {
		if (isset($exif_header['COMPUTED']['UserComment'])) {
			return $exif_header['COMPUTED']['UserComment'];
		}
		return NULL;
	}

	private function extractImageDescription($exif_header) {
		if (isset($exif_header['COMPUTED']['ImageDescription'])) {
			return $exif_header['COMPUTED']['ImageDescription'];
		}
		return NULL;
	}

	public function getMake() {
		return $this->make;
	}

	public function getModel() {
		return $this->model;
	}

	public function getExposureTime() {
		return $this->exposureTime;
	}

	public function getFNumber() {
		return $this->fNumber;
	}

	public function getFocalLength() {
		return $this->focalLength;
	}

	public function getIso() {
		return $this->iso;
	}

	public function getFlash() {
		return $this->flash;
	}

	public function getDateTime() {
		return $this->dateTime;
	}

	public function getJpegComment() {
		return $this->jpegComment;
	}

	public function getUserComment() {
		return $this->userComment;
	}

	public function getImageDescription() {
		return $this->imageDescription;
	}
}
?>
